package com.gan.simple_init.common.filter;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.gan.simple_init.common.base.ResponseErrorEnum;
import com.gan.simple_init.common.base.RestResultGenerator;
import com.gan.simple_init.service.impl.UserDetailsServiceImpl;
import com.gan.simple_init.util.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 自定义用户未登陆处理类
 */
@Component
public class RestAuthorizationEntryPoint implements AuthenticationEntryPoint {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private UserDetailsServiceImpl userDetailsServiceImpl;

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException authenticationException) throws IOException {
        // 使用流来向前端返回报错信息
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json");
        PrintWriter writer = httpServletResponse.getWriter();
        // 获取token
        String token = httpServletRequest.getHeader("token");
        if (StringUtils.isNotEmpty(token) && StringUtils.isNotEmpty(jwtTokenUtil.getUserNameFromToken(token))) {
            UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername(jwtTokenUtil.getUserNameFromToken(token));
            boolean tokenFlag = jwtTokenUtil.getTokenFlag(token);
            // 验证token是否有效,如果redis中存在token则需要对redis中的token相对应
            if (!jwtTokenUtil.validateToken(token, userDetails) && tokenFlag) {
                writer.write(new ObjectMapper().writeValueAsString(RestResultGenerator.error(ResponseErrorEnum.USER_REFRESH)));
                writer.flush();
                writer.close();
            }
        }
        writer.write(new ObjectMapper().writeValueAsString(RestResultGenerator.error(ResponseErrorEnum.USER_UN_LOGIN)));
        writer.flush();
        writer.close();
    }


}
